/**
 * This file is part of the dspace-poltman project http://www.poltman.com.
 *
 * This is free software; you can redistribute it and/or modify it under
 * the terms of DuraSpace DSpace license detailed in the LICENSE and NOTICE 
 * files at the root of the source tree and available online at
 * http://www.dspace.org/license/
 * 
 */
package com.poltman.dscentral.core.vm.menu;

import com.poltman.dscentral.core.CoreStatics;
import com.poltman.dscentral.core.webappinit.WebAppInit;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.zkoss.zk.ui.WebApp;

/**
 * 
 * @author z.ciok@poltman.com
 * @version $Revision: 1825 $
 *
 */
public class MainMenuVM extends MainMenuCommon implements Serializable {
	
	private static final long serialVersionUID = 7468293386516545358L;

	private static Logger log = Logger.getLogger(MainMenuVM.class);
	
	String message;
	List<MenuNode> nodes;

	//TODO: i18n
	public MainMenuVM() throws Exception {
		
		MenuNode node = null;
		
		nodes = new ArrayList<MenuNode>();
		
		//DSCentral
		node = new MenuNode(ml("main.dscentral"), isItemDisabled("main.dscentral"), null);
			MenuNode mainDSCentral = new MenuNode(ml("main.dscentral.menuPolicies"), isItemDisabled("main.dscentral.menuPolicies"), null);
				MenuNode mainDSCentralMenuPoliciesMenuGroups = new MenuNode(ml("main.dscentral.menuPolicies.menuGroups"), isItemDisabled("main.dscentral.menuPolicies.menuGroups"), "/pages/dscentral/menu-groups.zul");
				mainDSCentral.addChild(mainDSCentralMenuPoliciesMenuGroups);	
			node.addChild(mainDSCentral);
			//user profile
			MenuNode mainDSCentralMyProfile = new MenuNode(ml("main.dscentral.myProfile"), false, "/pages/register/my-profile.zul");  //always enabled
//				MenuNode mainDSCentralMyProfileRegistration = new MenuNode(ml("main.dscentral.myProfile.register"), isItemDisabled("main.dscentral.myProfile.register"), "/pages/register/registration-form.zul");
//				mainDSCentralMyProfile.addChild(mainDSCentralMyProfileRegistration);	
			node.addChild(mainDSCentralMyProfile);
			
		nodes.add(node);	
			
		//DSpace cfg
		node = new MenuNode(ml("main.dspaceCfg"), isItemDisabled("main.dspaceCfg"), null);
			MenuNode mainGeneralConfigurationsDSPaceConfig = new MenuNode(ml("main.dspaceCfg.generalConfiguration"), isItemDisabled("main.dspaceCfg.generalConfiguration"), "/pages/system/general-configurations.zul");
			node.addChild(mainGeneralConfigurationsDSPaceConfig);
		
			MenuNode mainAuthenticationDSPaceConfig = new MenuNode(ml("main.dspaceCfg.authentication"), isItemDisabled("main.dspaceCfg.authentication"), "/pages/system/authentication.zul");
			node.addChild(mainAuthenticationDSPaceConfig);
		nodes.add(node);
		
		//EPeople
		node = new MenuNode(ml("main.epeople"), isItemDisabled("main.epeople"), null);
			MenuNode mainEpeopleAdd = new MenuNode(ml("main.epeople.add"), isItemDisabled("main.epeople.add"), "/pages/epeople/add-epeople.zul");
			node.addChild(mainEpeopleAdd);
			MenuNode mainEpeopleSelect = new MenuNode(ml("main.epeople.select"), isItemDisabled("main.epeople.select"), null);
			node.addChild(mainEpeopleSelect);
			MenuNode mainEpeopleEdit = new MenuNode(ml("main.epeople.edit"), isItemDisabled("main.epeople.edit"), null);
			node.addChild(mainEpeopleEdit);
			MenuNode mainEpeopleDelete = new MenuNode(ml("main.epeople.delete"), isItemDisabled("main.epeople.delete"), null);
			node.addChild(mainEpeopleDelete);
		nodes.add(node);
		
		//Communities
		node = new MenuNode(ml("main.communities"), isItemDisabled("main.communities"), null);
			MenuNode mainCommunitiesBrowse = new MenuNode(ml("main.communities.browse"), isItemDisabled("main.communities.browse"), "/pages/communities/communities.zul");
			node.addChild(mainCommunitiesBrowse);
			MenuNode mainCommunitiesNewTopLevel = new MenuNode(ml("main.communities.newTopLevel"), isItemDisabled("main.communities.newTopLevel"), "/pages/communities/new-top-level-community.zul" );
			node.addChild(mainCommunitiesNewTopLevel);
			MenuNode mainCommunitiesNewCommunity = new MenuNode(ml("main.communities.newCommunity"), isItemDisabled("main.communities.newCommunity"), "/pages/communities/new-community.zul" );
			node.addChild(mainCommunitiesNewCommunity);
		nodes.add(node);
		
		//Collections
		node = new MenuNode(ml("main.collections"), isItemDisabled("main.collections"), null);
			MenuNode mainCollectionsBrowse = new MenuNode(ml("main.collections.browse"), isItemDisabled("main.collections.browse"), null);
			node.addChild(mainCollectionsBrowse);
			//TODO:
			MenuNode mainCollectionsNew = new MenuNode("New", false, null );
			node.addChild(mainCollectionsNew);
		nodes.add(node);
		
		this.addons();
		
		//Help
		node = new MenuNode("Help", false, null);
			//TODO:
			MenuNode mainHelp = new MenuNode("Help", false, null);
			node.addChild(mainHelp);
			//TODO:
			MenuNode mainHelpAbout = new MenuNode("About", false, null );
			node.addChild(mainHelpAbout);
		nodes.add(node);
		
	}

	private void addons() throws Exception {
		log.info("DSCentral append addons...");
		
		if (WebAppInit.getInstance() == null) {
			log.error("WebAppInit.getInstance() == null");
			throw new Exception("WebAppInit.getInstance() == null");
		}
		
		WebApp webApp = WebAppInit.getInstance().getWebApp();
		
		if (webApp == null) {
			log.error("webApp == null");
			throw new Exception("webApp == null");
		}
		
		String addonsFilePath = webApp.getRealPath(File.separator) + CoreStatics.ADDONS_PROPERTIES_FILE_RELATIVE_PATH;
		Properties pro = new Properties();
		try {
			FileInputStream in = new FileInputStream(addonsFilePath);
			pro.load(in);
			@SuppressWarnings("rawtypes")
			Enumeration em = pro.keys();
			while (em.hasMoreElements()) {
				String str = (String) em.nextElement();
				MenuNode menuNode = fetchMenus((String)pro.get(str));
				this.nodes.add(menuNode);
			}
		} catch (IOException e) {
			log.error(e);
			throw(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	private MenuNode fetchMenus(String addonClass) throws Exception {
		MenuNode menuNode = null;

			@SuppressWarnings("rawtypes")
			Class cl = null;
			try {
				cl = Class.forName(addonClass);
			} catch (ClassNotFoundException e) {
				log.error(e);
				throw (e);
			}
			
			Object clInstance = null;
			try {
				clInstance = cl.newInstance();
			} catch (InstantiationException e) {
				log.error(e);
				throw (e);
			} catch (IllegalAccessException e) {
				log.error(e);
				throw (e);
			}
			
			Method getNode = null;
			try {
				getNode = cl.getDeclaredMethod("getNode");
			} catch (SecurityException e) {
				log.error(e);
				throw (e);
			} catch (NoSuchMethodException e) {
				log.error(e);
				throw (e);
			}
			
			try {
				menuNode = (MenuNode) getNode.invoke(clInstance);
			} catch (IllegalArgumentException e) {
				log.error(e);
				throw (e);
			} catch (IllegalAccessException e) {
				log.error(e);
				throw (e);
			} catch (InvocationTargetException e) {
				log.error(e);
				throw (e);
			}
		
		return menuNode;
	}

	public List<MenuNode> getNodes() {
		return nodes;
	}

	MenuNode createNode(String name, int children, int nested) {
		MenuNode n = new MenuNode(name, false, null);
		if (nested > 0) {
			for (int i = 0; i < children; i++) {
				n.addChild(createNode(name + "_" + i, i == children - 1 ? 0
						: children, nested - 1));
			}
		}
		return n;
	}

	public String getMessage() {
		return message;
	}
	
	String action;
	public String getAction() {
		return action;
	}

/*	
	@Command
	//@NotifyChange({"action", "message"})
	//@NotifyChange("message")
	public void menuClicked(@BindingParam("node") MenuNode node) {
		//message = (String) node.getAction(); 
		action = (String) node.getAction();
		// !!!!!!!!!!!!!!!!!!!!!!!!!!!! FRAGMENTS !!!!!!!!!!!!!!!!!!!!!!!!!
		//Executions.sendRedirect("~./com/fragment.zul");
	}
*/	
}
